﻿using CLCommuConfig;
using CLVisionCommu;
using CLVisionTrace;
using NeuroCheck.BaseTypes.DataFormatConverter;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace CLVisionCommuDFC
{
    public class ChannelOptionManager
    {
        public int ChannelID;
        public List<PinInfoDataCustom> pinInfoDataList = new List<PinInfoDataCustom>();
        public dynamic commuOptionManager;
        List<int> m_alAssignedPinIDs;
  
        public ChannelOptionManager(int channelID, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            try
            {
             
                ChannelID = channelID;
                m_alAssignedPinIDs = new List<int>();
                Init(out ErrorCode, out ErrorText);
                if (ErrorCode == -1)
                {
                    if (commuOptionManager != null)
                    {
                        commuOptionManager.CommuOption.Dispose(out ErrorCode, out string _);
                        if (ErrorCode == -1)
                        {
                            return;
                        }
                        else
                        {
                            ErrorCode = -1;
                            ErrorText = ErrorText + "初始化失败！通讯已释放！";
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = ex.Message;
            }
        }

        private void Init(out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            try
            {
               string currentDirctory = @"V:\Ncheck\Software Extensions\x64\CLVisionCommu";
                //string configFilePath = Path.Combine(currentDirctory, "CLVisionCommuConfig.cdat");
                string configFilePath = @"V:\Ncheck\Configuration\Config\CLVisionCommuConfig.cdat";


                string dll = Path.Combine(currentDirctory, "CLVisionCommu.dll");
                Assembly assembly = Assembly.LoadFrom(dll);
                var types = assembly.GetTypes();
                var type = types.Where(x => x.Name == "CommuOptionManager").FirstOrDefault();
                commuOptionManager = Activator.CreateInstance(type) ;
                if (commuOptionManager==null)
                {
                    ErrorCode = -1;
                    ErrorText = "实例化通讯管理类失败！";
                    return;
                }
                commuOptionManager.Init(0, configFilePath, out ErrorCode, out ErrorText);
                if (ErrorCode == -1)
                {
                    return;
                }
                commuOptionManager.SwitchCommu(out ErrorCode, out ErrorText);
                if (ErrorCode == -1)
                {
                    return;
                }

                pinInfoDataList.Clear();

                ConfigOptionNC configOption = new ConfigOptionNC();
                string cdatFile = ReadFile(configFilePath, out ErrorCode, out ErrorText);


                configOption.InitConfig(cdatFile, out ErrorCode, out ErrorText);
                for (int i = 0; i < configOption.ParamDict.Keys.Count; i++)
                {
                    IObject key = configOption.ParamDict.Keys.ToArray()[i];
                    int objectID = key.ObjectID;
                    string objectName = key.Name;
                    for (int j = 0; j < configOption.ParamDict[key].Count; j++)
                    {
                        IObjectItem objectItem = configOption.ParamDict[key][j];
                        for (int k = 0; k < objectItem.Array; k++)
                        {
                            PinInfoDataCustom pinInfoData = new PinInfoDataCustom();
                            pinInfoData.DataType = (NcFmtCnvPinDataTypeInfo)Enum.Parse(typeof(NcFmtCnvPinDataTypeInfo), objectItem.NCPinDataTypeInfo.ToString());

                            pinInfoData.PinType = (NcFmtCnvPinTypeInfo)Enum.Parse(typeof(NcFmtCnvPinTypeInfo), objectItem.NCPinTypeInfo.ToString());

                            if (objectName == "ConstantParam")
                            {
                                pinInfoData.Name = objectItem.Name;
                                pinInfoData.Tag = ("Constant", objectItem.Array);
                            }
                            else
                            {
                                pinInfoData.Tag = ("Object", objectItem.Array);
                                pinInfoData.Name = $"[{objectID}.{j}.{k}]{objectItem.Type}({objectItem.Name})";
                            }

                            //一个地址存储多个bool数据
                            pinInfoData.Isbit = objectItem.IsBit;
                            pinInfoData.BitIndex = objectItem.BitIndex;

                            GetNextAvailablePinID(out int index);
                            pinInfoData.ID = index;
                            pinInfoData.UserDefinedName = pinInfoData.Name;
                            pinInfoDataList.Add(pinInfoData);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = ex.Message;
            }
        }


      
        protected string ReadFile(string filePath, out int ErrorCode, out string ErrorText)
        {
            ErrorCode = 0;
            ErrorText = "NoError";
            string result = null;
            try
            {
                using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    using (StreamReader streamReader = new StreamReader(fs, Encoding.UTF8))
                    {
                        result = streamReader.ReadToEnd();
                    }
                }
                return result;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "读取本地文件失败！" + ex.Message;
                return result;
            }
        }

        public void GetNextAvailablePinID(out int pinIndex)
        {
            m_alAssignedPinIDs.Sort();
            for (int i = 0; i < m_alAssignedPinIDs.Count; i++)
            {
                if (i != (int)m_alAssignedPinIDs[i])
                {
                    pinIndex = i;
                    m_alAssignedPinIDs.Add(pinIndex);
                    return;
                }
            }
            pinIndex = m_alAssignedPinIDs.Count;
            m_alAssignedPinIDs.Add(pinIndex);
        }


    }
}
